<!--
 * @Description: 总表单，引入各组件
-->
<template>
  <el-form
    :model="dataCopy"
    :rules="rules"
    :ref="ref"
    :inline-message="inlineMessage"
    @submit.native.prevent
    :label-width="`${String(labelWidth).replace('px', '')}px`"
    :class="[`_ehl_form ${customClass}`, { cpt_form_horizon: horizon }]"
  >
    <slot name="form_header" :data="generateParam()"></slot>
    <template v-for="(item, index) in optionsArray">
      <slot :name="`head_${index}`" :data="generateParam()"></slot>
      <el-form-item
        :class="[{ el_form_item_v: item.vertical }, item.lineClass]"
        :style="item.lineStyle || {}"
        v-if="item.show !== false"
        v-show="item.hidden !== true"
        :key="item.key"
        :label="
          typeof item.label === 'function'
            ? item.label(generateParam({ ...item, formIndex }))
            : item.label
        "
        :prop="item.key"
        :required="item.required"
        :label-width="
          item.labelWidthItem && `${String(item.labelWidthItem).replace('px', '')}px`
        "
      >
        <template v-slot:label v-if="item.labelSlot">
          <span
            :style="item.labelStyle"
            v-html="item.labelSlot(generateParam({ ...item, formIndex }))"
          ></span>
        </template>
        <!-- 按钮 -->
        <div
          v-if="item.type === 'button'"
          :class="['content_layout', item.class || '']"
          :style="{
            'justify-content':
              item.position === 'center'
                ? 'center'
                : item.position === 'right'
                ? 'flex-end'
                : 'flex-start',
            ...(item.style || {}),
          }"
        >
          <template v-for="(btn, num) in item.buttons">
            <div
              :key="num"
              v-if="btn.show !== false"
              :class="btn.class || ''"
              :style="btn.style || {}"
              :title="btn.title"
              @click="
                !(disabled || btn.disabled) && btn.click && btn.click(generateParam())
              "
              >{{ btn.name }}
            </div>
          </template>
        </div>
        <!-- 勾选框 -->
        <div
          :ref="item.key"
          v-if="item.type === 'check'"
          :class="item.class || ''"
          :style="item.style || {}"
          :title="item.label"
        >
          <el-checkbox
            v-model="dataCopy[item.key]"
            @change="
              val => {
                item.change && item.change(generateParam({ value: val }))
              }
            "
          >
          </el-checkbox>
        </div>
        <!-- 纯展示/自定义 -->
        <div
          :style="{ width: '100%' }"
          :ref="item.key"
          v-if="item.type === 'label'"
          @click="item.click && item.click(generateParam({ data: dataCopy[item.key] }))"
        >
          <slot :name="item.key" :data="generateParam({ data: dataCopy[item.key] })">
            <div
              :class="item.class || ''"
              :style="{
                'text-align':
                  item.position === 'center'
                    ? 'center'
                    : item.position === 'right'
                    ? 'right'
                    : 'left',
                ...(item.style || {}),
              }"
              :title="dataCopy[item.key] || item.default || ''"
            >
              {{
                dataCopy[item.key] !== undefined
                  ? dataCopy[item.key]
                  : item.default !== undefined
                  ? item.default
                  : ''
              }}
            </div>
          </slot>
        </div>
        <!-- 普通输入框 -->
        <ehl-input
          :ref="item.key"
          v-if="item.type === 'input'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :clearable="item.clearable"
          :rows="item.rows"
          :maxrows="item.maxrows"
          :disabled="disabled || item.disabled"
          :readonly="item.readonly"
          :password="item.password"
          :max="item.max"
          :limit="item.limit"
          :placeholder="item.placeholder"
          :prefix-icon="item.prefixIcon"
          :suffix-icon="item.suffixIcon"
          :format="item.format"
          @enter="
            val => {
              item.enter && item.enter(generateParam({ value: val }))
            }
          "
          @change="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
          @clear="
            val => {
              item.clear && item.clear(generateParam({ value: val }))
            }
          "
          @blur="
            val => {
              item.blur && item.blur(generateParam({ value: val }))
            }
          "
        />
        <!-- 带下拉提示的输入框 -->
        <ehl-autocomplete
          :ref="item.key"
          v-if="item.type === 'autocomplete'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :disabled="disabled || item.disabled"
          :placeholder="item.placeholder"
          :label-key="item.labelKey"
          :value-key="item.valueKey"
          :prefix-icon="item.prefixIcon"
          :suffix-icon="item.suffixIcon"
          :format="item.format"
          :max="item.max"
          :rows="item.rows"
          :maxrows="item.maxrows"
          @query="
            (queryString, cb) => {
              item.query && item.query(generateParam({ queryString, cb }))
            }
          "
          @onInput="
            val => {
              item.input && item.input(generateParam({ value: val }))
            }
          "
          @onChange="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
          @enter="
            val => {
              item.enter && item.enter(generateParam({ value: val }))
            }
          "
        />
        <!-- 数字输入框 -->
        <ehl-input-number
          :ref="item.key"
          v-if="item.type === 'inputNumber'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :disabled="disabled || item.disabled"
          :min="item.min"
          :max="item.max"
          :step="item.step"
          :placeholder="item.placeholder"
          :precision="item.precision"
          @change="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
        />
        <!-- 时间选择框 -->
        <ehl-date
          :ref="item.key"
          v-if="item.type === 'date'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :disabled="disabled || item.disabled"
          :date-type="item.dateType"
          :readonly="item.readonly"
          :show-slot="item.showSlot"
          :clearable="item.clearable"
          :devide="item.devide"
          :format="item.format"
          :start-placeholder="item.startPlaceholder"
          :end-placeholder="item.endPlaceholder"
          :picker-options="item.pickerOptions"
          @date-change="
            val => {
              item.dateChange && item.dateChange(generateParam({ value: val }))
            }
          "
        >
          <template v-slot:rangeradio="{ data }">
            <slot :name="item.key" :data="generateParam(data)"> </slot>
          </template>
        </ehl-date>
        <!-- 下拉选择框 -->
        <ehl-select
          :ref="item.key"
          v-if="item.type === 'select'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :options="item.options"
          :lazy="item.lazy"
          :clearable="item.clearable"
          :multiple="item.multiple"
          :disabled="disabled || item.disabled"
          :filterable="item.filterable"
          :placeholder="item.placeholder"
          :loadingtext="item.loadingtext"
          :allow-create="item.allowCreate"
          :defaultFirstOption="item.defaultFirstOption"
          :prop="item.prop"
          @init="
            (options, search) => {
              item.init &&
                item.init(generateParam({ options, search, value: dataCopy[item.key] }))
            }
          "
          @change="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
          @clear="
            val => {
              item.clear && item.clear(generateParam({ value: val }))
            }
          "
        />
        <!-- 下拉懒加载树 -->
        <ehl-select-lazy-tree
          :ref="item.key"
          v-if="item.type === 'selectLazyTree'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :disabled="disabled || item.disabled"
          :load-node="item.loadNode"
          :devide="item.devide"
          :prop="item.prop"
          @change="
            (val, data) => {
              item.change && item.change(generateParam({ value: val, data }))
            }
          "
        />
        <!-- 下拉选择树 -->
        <ehl-select-tree
          :ref="item.key"
          v-if="item.type === 'selectTree'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :tree="item.options"
          :lazy="item.lazy"
          :clearable="item.clearable"
          :check-strictly="item.checkStrictly"
          :disabled="disabled || item.disabled"
          :filterable="item.filterable"
          :show-checkbox="item.showcheckbox"
          :placeholder="item.placeholder"
          :indent="item.indent"
          :accordion="item.accordion"
          :expand-on-click-node="item.expandOnClickNode"
          :default-expand-all="item.defaultExpandAll"
          :loadingtext="item.loadingtext"
          :devide="item.devide"
          :only-leaf-node-can-click="item.onlyLeafNodeCanClick"
          :prop="item.prop"
          @init="
            (options, search) => {
              item.init &&
                item.init(generateParam({ options, search, value: dataCopy[item.key] }))
            }
          "
          @change="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
        />
        <!-- 单选框 -->
        <ehl-radio-group
          :ref="item.key"
          v-if="item.type === 'radioGroup'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :options="item.options"
          :disabled="disabled || item.disabled"
          :prop="item.prop"
          @init="
            options => {
              item.init && item.init(generateParam({ options }))
            }
          "
          @change="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
        >
          <template v-for="i in item.options" v-slot:[i.slot]="{ data }">
            <slot :name="i.slot" :data="generateParam(data)"> </slot>
          </template>
        </ehl-radio-group>
        <!-- 多选框 -->
        <ehl-check-group
          :ref="item.key"
          v-if="item.type === 'checkGroup'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :options="item.options"
          :disabled="disabled || item.disabled"
          :prop="item.prop"
          @init="
            options => {
              item.init && item.init(generateParam({ options }))
            }
          "
          @change="
            val => {
              item.change && item.change(generateParam({ value: val }))
            }
          "
        >
          <template v-for="i in item.options" v-slot:[i.slot]="{ data }">
            <slot :name="i.slot" :data="generateParam(data)"> </slot>
          </template>
        </ehl-check-group>
        <!-- 普通展示表格 -->
        <ehl-table
          :ref="item.key"
          v-if="item.type === 'table'"
          :class="item.class || ''"
          :style="item.style || {}"
          :row-key="item.rowKey"
          :table-data="dataCopy[item.key]"
          :table-columns="item.columns"
          :max-height="item.maxHeight"
          :default-sort="item.defaultSort"
          :use-page="item.usePage"
          :border="item.border"
          :current-page="item.page"
          :filter-single="item.filterSingle"
          :page-size="item.size"
          :page-sizes="item.sizes"
          :total="item.total"
          :layout="item.layout"
          :position="item.position"
          :rowClassName="item.rowClassName"
          @init="
            (column, data) => {
              item.init && item.init(generateParam({ column, data }))
            }
          "
          @sort="
            (order, field, column, data) =>
              item.sortChange &&
              item.sortChange(generateParam({ order, field, column, data }))
          "
          @page-change="
            (page, column, data) =>
              item.pageChange && item.pageChange(generateParam({ page, column, data }))
          "
          @size-change="
            (size, column, data) =>
              item.sizeChange && item.sizeChange(generateParam({ size, column, data }))
          "
          @filter-change="
            (filters, column, data) =>
              item.filterChange &&
              item.filterChange(generateParam({ filters, column, data }))
          "
          @selection-change="
            (selection, column, data) =>
              item.selectionChange &&
              item.selectionChange(generateParam({ selection, column, data }))
          "
          @column-click="
            (callback, data) => {
              callback(generateParam({ ...data }))
            }
          "
        >
          <template v-slot:operation="rowData">
            <slot :name="item.key" :data="generateParam(rowData.data)"> </slot>
          </template>
          <template v-for="(item, index) in item.columns" v-slot:[item.slot]="rowData">
            <div class="table_custom_slot" :key="index">
              <slot :name="item.slot" :data="generateParam(rowData.data)"> </slot>
            </div>
          </template>
        </ehl-table>
        <!-- 自定义表格 -->
        <ehl-cus-table
          :ref="item.key"
          v-if="item.type === 'ehlCusTable'"
          :class="item.class || ''"
          :style="item.style || {}"
          :column="item.column"
          :data="dataCopy[item.key]"
          :title="item.title"
          :tool="item.tool"
          :show-ctrl="item.showCtrl"
          :select="item.select"
          :show-index="item.showIndex"
          :form-data="dataCopy"
          :form-options="optionsCopy"
          :other-param="otherParam"
          @add="item.addItem(generateParam({ currentArr: dataCopy[item.key] }))"
          @delete="
            selectArr =>
              item.delItem(generateParam({ selectArr, currentArr: dataCopy[item.key] }))
          "
        >
          <slot :name="item.key" :data="generateParam({})"> </slot>
        </ehl-cus-table>
        <!-- 多功能表格 -->
        <ehl-mul-table
          :ref="item.key"
          v-if="item.type === 'mulTable'"
          :class="item.class || ''"
          :style="item.style || {}"
          :column="item.column"
          :data="dataCopy[item.key]"
          :select="item.select"
          :tool="item.tool"
          :placeholder="item.placeholder"
          @add="item.add && item.add(generateParam({ array: dataCopy[item.key] }))"
          @delete="
            delArr =>
              item.del &&
              multable.del(generateParam({ delArr, array: dataCopy[item.key] }))
          "
        />
        <!-- 平铺展示器 -->
        <ehl-tiling
          :ref="item.key"
          v-if="item.type === 'tiling'"
          :class="item.class || ''"
          :style="item.style || {}"
          :data="dataCopy[item.key]"
          :no-deta-txt="item.noDetaTxt"
          :min-width="item.minWidth"
          :columns="item.columns"
        >
          <template v-slot:tiling="{ data }">
            <slot :name="item.key" :data="generateParam(data)"> </slot>
          </template>
        </ehl-tiling>
        <!-- 代码编辑器 -->
        <ehlCode
          :ref="item.key"
          v-if="item.type === 'code'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :mode="item.mode"
          :theme="item.theme"
          :hits="item.hits"
          :readonly="item.readonly"
          :auto-format="item.autoFormat"
          :tool="item.tool"
        />
        <!-- 搜索树 -->
        <ehl-tree
          :ref="item.key"
          v-if="item.type === 'tree'"
          :options="item.options"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :max="item.max"
          :rows="item.rows"
          :limit="item.limit"
          :clearable="item.clearable"
          :placeholder="item.placeholder"
          :prefix-icon="item.prefixIcon"
          :suffix-icon="item.suffixIcon"
          :format="item.format"
          :lazy="item.lazy"
          :indent="item.indent"
          :accordion="item.accordion"
          :checkbox="item.checkbox"
          :node-key="item.nodeKey"
          :check-strictly="item.checkStrictly"
          :highlight-current="item.highlightCurrent"
          :default-expand-all="item.defaultExpandAll"
          :default-expanded-keys="item.defaultExpandedKeys"
          :check-on-click-node="item.checkOnClickNode"
          :show-all="item.showAll"
          :show-tool="item.showTool"
          :input-show="item.inputShow"
          :auto-select="item.autoSelect"
          :auto-remember="item.autoRemember"
          :is-leaf-prop="item.isLeafProp"
          :prop="item.prop"
          :filter-node="
            (value, data) =>
              item.filterNode && item.filterNode(generateParam({ value, data }))
          "
          :loadNode="
            (node, resolve) =>
              item.loadNode && item.loadNode(generateParam({ node, resolve }))
          "
          @init="options => item.init && item.init(generateParam({ options }))"
          @txt-change="
            (options, search) =>
              item.txtChange && item.txtChange(generateParam({ options, search }))
          "
          @clear="
            (options, search) =>
              item.clear && item.clear(generateParam({ options, search }))
          "
          @enter="
            (options, search) => {
              item.enter && item.enter(generateParam({ options, search }))
              item.search && item.search(generateParam({ options, search }))
            }
          "
          @search="
            (options, search) =>
              item.search && item.search(generateParam({ options, search }))
          "
          @node-click="node => item.nodeClick && item.nodeClick(generateParam({ node }))"
          @node-expand="
            (options, node) =>
              item.nodeExpand && item.nodeExpand(generateParam({ options, node }))
          "
          @node-collapse="
            (options, node) =>
              item.nodeCollapse && item.nodeCollapse(generateParam({ options, node }))
          "
        >
          <template v-slot:blank0="{ data }">
            <slot :name="`${item.key}0`" :data="generateParam(data)"></slot>
          </template>
          <template v-slot:blank1="{ data }">
            <slot :name="`${item.key}1`" :data="generateParam(data)"></slot>
          </template>
          <template v-slot:blank2="{ data }">
            <slot :name="`${item.key}2`" :data="generateParam(data)"></slot>
          </template>
          <template v-slot:tree_root="{ data }">
            <slot :name="`${item.key}_root`" :data="generateParam(data)"></slot>
          </template>
          <template v-slot:tree_leaf="{ data }">
            <slot :name="`${item.key}_leaf`" :data="generateParam(data)"></slot>
          </template>
        </ehl-tree>
        <!-- 分页信息 -->
        <ehl-page
          :ref="item.key"
          v-if="item.type === 'page'"
          :class="item.class || ''"
          :style="item.style || {}"
          :current-page="item.page"
          :page-sizes="item.sizes"
          :page-size="item.size"
          :total="item.total"
          :layout="item.layout"
          :small="item.small"
          :position="item.position"
          @size-change="size => item.sizeChange(generateParam({ size }))"
          @current-change="page => item.pageChange(generateParam({ page }))"
        />
        <!-- tabs单选标签组 -->
        <ehl-tabs
          :ref="item.key"
          v-if="item.type === 'tabs'"
          :class="item.class || ''"
          :style="item.style || {}"
          v-model="dataCopy[item.key]"
          :list="item.list"
          :prop="item.prop"
          :clickable="item.clickable"
          :min-width="item.minWidth"
          :max-width="item.maxWidth"
          :show-del-icon="item.showDelIcon"
          :cus-tab-class="item.cusTabClass"
          :show-next-icon="item.showNextIcon"
          @tab-click="
            (select, index) =>
              item.tabClick && item.tabClick(generateParam({ select, index }))
          "
          @tab-del="
            (del, index) => item.tabDel && item.tabDel(generateParam({ del, index }))
          "
        />
        <!-- tabs多选标签组 -->
        <ehl-mul-tabs
          :ref="item.key"
          v-if="item.type === 'multabs'"
          v-model="dataCopy[item.key]"
          :class="item.class || ''"
          :style="item.style || {}"
          :list="item.list"
          :prop="item.prop"
          :show-next-icon="item.showNextIcon"
          @tab-click="select => item.tabClick && item.tabClick(generateParam({ select }))"
        >
          <template v-slot:multabs="{ data }">
            <slot :name="`${item.key}_multabs`" :data="generateParam(data)"></slot>
          </template>
        </ehl-mul-tabs>
        <!-- 加减项盒子 -->
        <ehl-edit-box
          :ref="item.key"
          v-if="item.type === 'editbox'"
          :class="item.class || ''"
          :style="item.style || {}"
          v-model="dataCopy[item.key]"
          :options="item.options"
          :show-edit-btn="item.showEditBtn"
          :label-width="item.labelWidth"
          :disabled="item.disabled"
          :inline-message="item.inlineMessage"
          :default-value="item.defaultValue"
        />
        <!-- pdf预览 -->
        <ehl-pdf
          :ref="item.key"
          v-if="item.type === 'pdf'"
          :class="item.class || ''"
          :style="item.style || {}"
          :url="item.url"
          :page="item.page"
          :link-allow="item.linkAllow"
        >
          <template v-slot:pdf_page="{ data }">
            <slot
              :name="`${item.key}_pdf_page`"
              :data="generateParam({ ...data })"
            ></slot>
          </template>
        </ehl-pdf>
        <!-- 穿梭框 -->
        <ehl-shuttle-box
          :ref="item.key"
          v-if="item.type === 'shuttle'"
          :class="item.class || ''"
          :style="item.style || {}"
          :left-form="item.form"
          :left-data="item.data"
          :right-form="item.rightForm"
          :prop="item.prop"
          v-model="dataCopy[item.key]"
        />
        <!-- cron表达式 -->
        <ehl-cron
          :ref="item.key"
          v-if="item.type === 'cron'"
          :class="item.class || ''"
          :style="item.style || {}"
          :disabled="item.disabled"
          v-model="dataCopy[item.key]"
        />
        <!-- step标签框 -->
        <ehlStep
          :ref="item.key"
          v-if="item.type === 'step'"
          :class="item.class || ''"
          :style="item.style || {}"
          :step="item.step"
          :space="item.space"
          :vertical-mode="item.verticalMode"
          :init-tab="item.initTab"
          :time-mode="item.timeMode"
          :prop="item.prop"
          @click="step => item.click && item.click(generateParam({ step }))"
        />
        <!-- 上传组件 -->
        <ehl-upload
          :ref="item.key"
          v-if="item.type === 'upload'"
          :class="item.class || ''"
          :style="item.style || {}"
          :multiple="item.multiple"
          :headers="item.headers"
          :drag="item.drag"
          :action="item.action"
          :hit="item.hit"
          :limit="item.limit"
          :accept="item.accept"
          :file-list="item.fileList"
          :show-file-list="item.showFileList"
          :uploadKey="item.uploadKey"
          @success="
            (response, file, fileList) =>
              item.success && item.success(generateParam({ response, file, fileList }))
          "
          @error="
            (err, file, fileList) =>
              item.error && item.error(generateParam({ err, file, fileList }))
          "
          @change="
            (file, fileList) =>
              item.change && item.change(generateParam({ file, fileList }))
          "
          @remove="
            (file, fileList) =>
              item.remove && item.remove(generateParam({ file, fileList }))
          "
        >
          <template v-slot:tip="{ data }">
            <slot :name="`${item.key}_tip`" :data="generateParam(data)"></slot>
          </template>
          <template v-slot:upload="{ data }">
            <slot :name="`${item.key}`" :data="generateParam(data)"></slot>
          </template>
          <template v-slot="{ data }">
            <slot :name="`${item.key}_div`" :data="generateParam(data)"></slot>
          </template>
        </ehl-upload>
        <!-- 富文本编辑器 -->
        <ehl-rich-edit
          :ref="item.key"
          v-if="item.type === 'rich'"
          :class="item.class || ''"
          :style="item.style || {}"
          :height="item.height"
          v-model="dataCopy[item.key]"
        />
        <!-- 可编辑div -->
        <ehl-edit-div
          :ref="item.key"
          v-if="item.type === 'editDiv'"
          :class="item.class || ''"
          :style="item.style || {}"
          v-model="dataCopy[item.key]"
          :prop="item.prop"
          :padding="item.padding"
          :height="item.height"
          :fillColor="item.fillColor"
          :fontSize="item.fontSize"
          :fontColor="item.fontColor"
        />
        <!-- 导航栏 -->
        <ehl-nav-menu
          :ref="item.key"
          v-if="item.type === 'navMenu'"
          :class="item.class || ''"
          :style="item.style || {}"
          :activeIndex="item.activeIndex"
          :menu="item.menu"
          :prop="item.prop"
          @click="
            (key, keyPath) => {
              item.click && item.click(generateParam({ key, keyPath }))
            }
          "
        />
        <!-- 可折叠导航栏 -->
        <ehl-menu
          :ref="item.key"
          v-if="item.type === 'menu'"
          :class="item.class || ''"
          :style="item.style || {}"
          :activeIndex="item.activeIndex"
          :menu="item.menu"
          :prop="item.prop"
          @click="
            (key, keyPath) => {
              item.click && item.click(generateParam({ key, keyPath }))
            }
          "
          @open="
            (key, keyPath) => {
              item.open && item.open(generateParam({ key, keyPath }))
            }
          "
          @close="
            (key, keyPath) => {
              item.close && item.close(generateParam({ key, keyPath }))
            }
          "
        />
        <!-- excel -->
        <ehl-excel
          :ref="item.key"
          v-if="item.type === 'excel'"
          :class="item.class || ''"
          :style="item.style || {}"
          :value="item.value"
          :config="item.config"
          :read-only="item.readOnly"
          :import-btn="item.importBtn"
          :export-btn="item.exportBtn"
          :default-config="item.defaultConfig"
        />
      </el-form-item>
      <slot :name="index" :data="generateParam()"></slot>
    </template>
    <div v-if="btnShow" class="slot_btn">
      <slot name="btn" :data="generateParam({ ref: $refs[ref] })"></slot>
    </div>
    <img
      :src="imgPath"
      ref="flexibleResize"
      class="_ehl_form_resize"
      title="收缩侧边栏"
      v-if="resizeShow === true"
      :resizeMinWidth="resizeMinWidth"
      :resizeMaxWidth="resizeMaxWidth"
    />
  </el-form>
</template>
<script>
  import Vue from 'vue'
  import { Form, FormItem, Checkbox } from 'element-ui'
  Vue.use(Form)
  Vue.use(FormItem)
  Vue.use(Checkbox)
  export default {
    name: 'ehlForm',
    components: {
      ehlInput: () => $import('ehlInput'),
      ehlAutocomplete: () => $import('ehlAutocomplete'),
      ehlSelect: () => $import('ehlSelect'),
      ehlSelectTree: () => $import('ehlSelectTree'),
      ehlInputNumber: () => $import('ehlInputNumber'),
      ehlRadioGroup: () => $import('ehlRadioGroup'),
      ehlCheckGroup: () => $import('ehlCheckGroup'),
      ehlCode: () => $import('ehlCode'),
      ehlTable: () => $import('ehlTable'),
      ehlCusTable: () => $import('ehlCusTable'),
      ehlMulTable: () => $import('ehlMulTable'),
      ehlTree: () => $import('ehlTree'),
      ehlTiling: () => $import('ehlTiling'),
      ehlDate: () => $import('ehlDate'),
      ehlPage: () => $import('ehlPage'),
      ehlTabs: () => $import('ehlTabs'),
      ehlMulTabs: () => $import('ehlMulTabs'),
      ehlEditBox: () => $import('ehlEditBox'),
      ehlPdf: () => $import('ehlPdf'),
      ehlShuttleBox: () => $import('ehlShuttleBox'),
      ehlCron: () => $import('ehlCron'),
      ehlSelectLazyTree: () => $import('ehlSelectLazyTree'),
      ehlStep: () => $import('ehlStep'),
      ehlUpload: () => $import('ehlUpload'),
      ehlRichEdit: () => $import('ehlRichEdit'),
      ehlEditDiv: () => $import('ehlEditDiv'),
      ehlNavMenu: () => $import('ehlNavMenu'),
      ehlMenu: () => $import('ehlMenu'),
      ehlExcel: () => $import('ehlExcel'),
    },
    props: {
      data: { type: Object, default: () => {} },
      options: { type: Object, default: () => {} },
      //label的宽度
      labelWidth: { type: Number, default: () => 100 },
      //自定义类名
      customClass: { type: String, default: () => '' },
      //是否显示表单最后的按钮插槽
      btnShow: { type: Boolean, default: () => true },
      //水平模式
      horizon: { type: Boolean, default: () => false },
      //是否整体禁用所有元素
      disabled: { type: Boolean, default: () => false },
      //错误显示在行的结尾而不是下部
      inlineMessage: { type: Boolean, default: () => false },
      //用于接收其他form的配置
      otherParam: { type: Object, default: () => ({}) },
      //拖动div的最小宽度
      resizeMinWidth: { type: String, default: () => '200' },
      //拖动div的最大宽度
      resizeMaxWidth: { type: String, default: () => '500' },
      //拖动把柄是否展示
      resizeShow: { type: Boolean, default: () => false },
      //当一个组件中包含多个form时候用于区分
      formIndex: { type: Number, default: () => 0 },
    },
    watch: {
      data: {
        handler(val, old) {
          // console.log('form data change:', val)
          this.dataCopy = val
        },
        deep: true, //为true，表示深度监听，这时候就能监测到a值变化
      },
      options: {
        handler: function (val, old) {
          this.optionsArray = this.deepCopy(val || {}, this.optionsCopy)
          this.optionsArray.map(i => {
            this.rules[i.key] = i.rule
          })
        },
        deep: true,
      },
    },
    data() {
      return {
        ref: `form_ref_${Math.random()}`,
        rules: {}, //表单验证规则集合
        dataCopy: this.data || {}, //原始数据的浅拷贝
        optionsArray: [], //用于循环生成表单
        optionsCopy: {}, //原配置的深拷贝副本，用于当作参数传递出去
        imgPath: require('@/common/assets/drag.png'),
      }
    },
    created() {
      this.optionsArray = this.deepCopy(this.options || {}, this.optionsCopy)
      this.optionsArray.map(i => {
        this.rules[i.key] = i.rule
      })
      this.otherParam.vue = this.$parent
    },
    mounted() {
      this.dragResizeDiv()
    },
    methods: {
      //参数必须是对象
      addParam(object) {
        Object.assign(this.otherParam, object || {})
      },
      //获取参数中的通用data
      getData() {
        return this.generateParam({})
      },
      //生成通用参数
      generateParam(param = {}) {
        return Object.assign(
          {},
          { current: param },
          {
            formOptions: this.optionsCopy,
            formData: this.dataCopy,
            formRefs: this.$refs,
          },
          { other: this.otherParam || {} },
        )
      },
      //将rule统一抽出来
      dealOptionArrayWithRule() {
        this.optionsArray = this.deepCopy(this.options || {}, this.optionsCopy)
        this.optionsArray.map(i => {
          this.rules[i.key] = i.rule
        })
      },
      //根据原配置文件生成新的配置数组
      deepCopy(obj, param) {
        Object.keys(obj).forEach(key => {
          obj[key].key = key
        })
        // let arr = []
        Object.values(obj).forEach(i => {
          let tmp = this.deepCopy2(i)
          param[tmp['key']] = tmp
          // arr.push(tmp)
        })
        return Object.values(param)
      },
      //深拷贝原配置文件
      deepCopy2(obj) {
        let tmp = {}
        Object.keys(obj).forEach(key => {
          if (obj[key] === undefined || obj[key] === null) {
            tmp[key] = null
          } else if (Array.isArray(obj[key])) {
            tmp[key] = []
            obj[key].forEach(i => {
              if (typeof i === 'object') {
                tmp[key].push(this.deepCopy2(i))
              } else {
                tmp[key].push(i)
              }
            })
          } else if (typeof obj[key] === 'object') {
            tmp[key] = this.deepCopy2(obj[key])
          } else {
            tmp[key] = obj[key]
          }
        })
        return tmp
      },
      getOptions() {
        return this.optionsCopy
      },
      async validate() {
        try {
          let re = await this.$refs[this.ref].validate()
          if (re) {
            return Promise.resolve(re)
          } else {
            return Promise.reject(re)
          }
        } catch (error) {
          console.log(error)
          return Promise.reject(false)
        }
      },
      dragResizeDiv() {
        let that = this
        // 鼠标按下事件
        document.onmousedown = function (e) {
          if (e.target.className === '_ehl_form_resize') {
            let resize = e.target
            let left = document.getElementsByClassName(resize.parentNode.className)
            //颜色改变提醒
            // resize.style.background = '#8d8d8d'
            let startX = e.clientX //鼠标距离浏览器x轴的位置
            resize.left = resize.offsetLeft

            // 鼠标拖动事件
            document.onmousemove = function (e) {
              let endX = e.clientX
              let moveLen = resize.left + (endX - startX) // （endx-startx）=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度

              // if (moveLen < that.resizeMinWidth) moveLen = that.resizeMinWidth // 左边区域的最小宽度
              // if (moveLen > that.resizeMaxWidth) moveLen = that.resizeMaxWidth // 左边区域的最大宽度

              if (moveLen < parseInt(resize.attributes.resizeMinWidth.nodeValue))
                moveLen = parseInt(resize.attributes.resizeMinWidth.nodeValue) // 左边区域的最小宽度
              if (moveLen > parseInt(resize.attributes.resizeMaxWidth.nodeValue))
                moveLen = parseInt(resize.attributes.resizeMaxWidth.nodeValue) // 左边区域的最大宽度

              resize.style.left = moveLen // 设置左侧区域的宽度
              left[0].style.width = moveLen + 'px'
            }
            // 鼠标松开事件
            document.onmouseup = function (evt) {
              //颜色恢复
              // resize.style.background = '#d6d6d6'
              document.onmousemove = null
              document.onmouseup = null
              resize.releaseCapture && resize.releaseCapture() //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
            }
            resize.setCapture && resize.setCapture() //该函数在属于当前线程的指定窗口里设置鼠标捕获
            return false
          }
        }
      },
    },
  }
</script>
